package com.weiyuanstudio.nextstep.configuration;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableMethodSecurity
public class SpringSecurityConfig {
    private ProjectConfiguration projectConfiguration;

    public SpringSecurityConfig(ProjectConfiguration projectConfiguration) {
        this.projectConfiguration = projectConfiguration;
    }

    /**
     * 配置Spring Security安全链
     * @param httpSecurity httpSecurity
     * @return SecurityFilterChain
     * @throws Exception unknown
     */
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
        if (projectConfiguration.isDebugMode()) return debugAllowAll(httpSecurity);
        return productMode(httpSecurity);
    }

    /**
     * 生产模式启动
     * @param httpSecurity
     * @return
     * @throws Exception
     */
    private SecurityFilterChain productMode(HttpSecurity httpSecurity) throws Exception {
        return httpSecurity
                .csrf(AbstractHttpConfigurer::disable)
                .authorizeHttpRequests(auth -> auth
                        .anyRequest().authenticated()
                )
                .sessionManagement(sess -> sess.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                .httpBasic(Customizer.withDefaults())
                .build();
    }

    /**
     * Debug 允许所有的请求无需登陆
     * @param httpSecurity
     * @return
     */
    private SecurityFilterChain debugAllowAll(HttpSecurity httpSecurity) throws Exception {
        return httpSecurity
                .csrf(AbstractHttpConfigurer::disable)
                .authorizeHttpRequests(auth -> auth
                        .requestMatchers("/**").permitAll()
                        .requestMatchers("/").permitAll()
                        .anyRequest().permitAll()
                )
                .sessionManagement(sess -> sess.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                .httpBasic(Customizer.withDefaults())
                .build();
    }
}
